<template>
  <div class="">
    <div class="crumbs">
      <el-breadcrumb separator="/">
        <el-breadcrumb-item>
          <i class="el-icon-coin"></i> 我的模型
        </el-breadcrumb-item>
      </el-breadcrumb>
    </div>

    <div class="container">
      <el-table
          :data="tableData" border class="table" ref="multipleTable"
          header-cell-class-name="table-header"
          @selection-change="handleSelectionChange"
          @row-dblclick="getConfigDetail"
      >
        <el-table-column prop="modelName" label="模型名"></el-table-column>
        <el-table-column prop="configName" label="所属配置"></el-table-column>
        <el-table-column label="模型算法">
          <template #default="scope">{{ handleAlgorithmName(scope.row.machineLearningAlgorithm) }}</template>
        </el-table-column>
        <el-table-column prop="arguments" label="参数值" :show-overflow-tooltip="true">
          <template #default="scope">
            <div v-for="(item,index) in scope.row.trainParams" :key="index">{{item}}</div>
          </template>
        </el-table-column>
        <el-table-column prop="trainedStatus" label="训练状态">
          <template #default="scope">
            <div v-if="scope.row.trainingState==='SUCCESS'" >
              <el-button type="text" class="yellow" @click="handleTrainRes(scope.$index, scope.row)">查看训练结果</el-button>
            </div>
            <div v-else-if="scope.row.trainingState==='ON_GOING'">
              <el-button type="text" class="green" >训练中</el-button>
            </div>
            <div v-else-if="scope.row.trainingState==='FAIL'">
              <el-button type="text" class="red" >训练失败</el-button>
            </div>
            <div v-else>
              <el-button type="text" class="green" @click="handleTrain(scope.row.id)">模型训练</el-button>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="预测结果">
          <template #default="scope">
            <div v-if="scope.row.trainingState==='SUCCESS'" >
              <el-button type="text" class="orange" @click="handlePreList(scope.row.id)">查看预测结果</el-button>
            </div>
            <div v-else>
              <el-button type="text" style="color: gray" disabled>查看预测结果</el-button>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="180" align="center">
          <template #default="scope">
            <div v-if="scope.row.trainingState==='SUCCESS'">
              <el-button type="text" @click="editUseModel(scope.row.id)">模型使用</el-button>
              <el-button type="text" @click="handleDeploy(scope.row.id)">部署</el-button>
              <el-button type="text" @click="handlePipeline(scope.row.id)">新建流水线
              </el-button>
            </div>
            <div v-else>
              <el-button type="text" style="color: gray" disabled>暂未成功训练</el-button>
            </div>
            <el-button type="text" class="yellow" @click="handleShare(scope.$index, scope.row)">分享</el-button>
            <el-button type="text" class="red" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="pagination">
        <el-pagination background layout="total, prev, pager, next" :current-page="query.pageIndex"
                       :page-size="query.pageSize" :total="pageTotal" @current-change="handlePageChange"></el-pagination>
      </div>
    </div>

      <el-dialog
        v-model="useModelVisible"
        title="模型使用"
        width="30%"
        :before-close="handleClose"
      >
            <el-form :model="useform" width="300px">
              <el-form-item label="选择文件" >
                <el-select v-model="useform.file" :label-width="formLabelWidth" placeholder="请选择您要使用的文件">
                  <el-option
                    v-for="item in fileList.valueOf()"
                    :key="item.id"
                    :label="item.fileName"
                    :value="item.id"
                  />
                </el-select>
              </el-form-item>
            </el-form>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="useModelVisible = false">取消</el-button>
            <el-button type="primary" @click="useModel(useform.file)" style="margin-left: 10px"> 使用模型 </el-button>
          </span>
        </template>
      </el-dialog>

    <el-dialog
        v-model="pipelineVisible"
        title="新建流水线"
        width="30%"
        :before-close="handleClose"
    >
      <el-form width="300px">
        <el-form-item label="流水线名称" required>
          <el-input v-model="pplForm.pipelineName"></el-input>
        </el-form-item>
        <el-form-item label="机器学习算法：" >
          {{pplForm.machineLearningAlgorithm}}
        </el-form-item>
        <el-form-item label="训练参数：" >
          {{pplForm.trainParams}}
        </el-form-item>
        <el-form-item label="特征：" >
          {{pplForm.features}}
        </el-form-item>
        <el-form-item label="标签：" >
          {{pplForm.label}}
        </el-form-item>
      </el-form>
      <template #footer>
          <span class="dialog-footer">
            <el-button @click="pipelineVisible = false">取消</el-button>
            <el-button type="primary" @click="pipeline()" style="margin-left: 10px"> 新建流水线 </el-button>
          </span>
      </template>
    </el-dialog>

    <el-dialog
        v-model="deployVisible"
        title="新建部署"
        width="30%"
        :before-close="handleClose"
    >
      <el-form width="300px">
        <el-form-item label="部署" required>
          <el-input v-model="deployName"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
          <span class="dialog-footer">
            <el-button @click="deployVisible = false">取消</el-button>
            <el-button type="primary" @click="goDeploy()" style="margin-left: 10px"> 部署 </el-button>
          </span>
      </template>
    </el-dialog>

  </div>

</template>

<script>
import { ref, reactive } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {addDeployment, getAllModel, getOneModel, train} from "../../api/model";
import {use} from "../../api/prediction";
import {GetAllFile} from "../../api/file";
import {useRoute, useRouter} from "vue-router";
import {deleteModel} from "../../api/model";
import {getOneConfig} from "../../api/config";
import {addPipeline} from "../../api/pipeline";
import {getCollectFileList, shareModel} from "../../api/square";

export default {
  name: "model",
  setup() {
    const router = useRouter();
    const useModelVisible = ref(false)
    const formLabelWidth='120px';
    const query = reactive({
      file: "",
      name: "",
      pageIndex: 1,
      pageSize: 10,
    });

    const fileList=ref();
    const multipleSelection =ref([]);
    const tableData = ref();
    let deployVisible = ref(false)
    let deployName = ref()
    let deployModel = ref()

    const pageTotal = ref(0);
    let pipelineVisible = ref(false)
    const pplForm = reactive({
      configId: '',
      pipelineName: '',
      features: [],
      label: '',
      machineLearningAlgorithm: {},
      trainParams: {},
    })
    const handlePipeline = (modelId) => {
      pipelineVisible.value = true
      const payload = {
        userId: localStorage.getItem("ms_userId"),
        modelId: modelId
      }
      getOneModel(payload).then(res =>{
        pplForm.configId = res.result.configId
        pplForm.machineLearningAlgorithm = res.result.machineLearningAlgorithm
        pplForm.trainParams = res.result.trainParams
        const data = {
          userId: localStorage.getItem("ms_userId"),
          configId: pplForm.configId
        }
        getOneConfig(data).then(resConfig =>{
          pplForm.features = resConfig.result.features
          pplForm.label = resConfig.result.label
        })
      })
    }
    const pipeline = () => {
      const payload = {
        userId: localStorage.getItem("ms_userId"),
        pipelineName: pplForm.pipelineName,
        features: pplForm.features,
        label: pplForm.label,
        machineLearningAlgorithm: pplForm.machineLearningAlgorithm,
        trainParams: pplForm.trainParams,
      }
      if (payload.pipelineName === ""){
        alert("请填写信息！")
        return
      }
      addPipeline(payload).then(res => {
        if (res.msg === '成功'){
          pipelineVisible.value = false
          ElMessageBox({
            title: '流水线',
            message: `加入流水线成功`,
            confirmButtonText: '确定',
          })
        }
        else{
          ElMessage.error("失败!:"+res.msg);
        }
      })
    }
    // 获取表格数据

    const getpage=()=> {
      const userId=localStorage.getItem("ms_userId");
      GetAllFile(userId).then(res=>{
        let myfile = res;
        getCollectFileList(userId).then(res=>{
          fileList.value = myfile.result.concat(res.result);
        })
      })
      getAllModel({
         userId: userId
      }).then(res => {
        tableData.value = res.result;
        pageTotal.value=tableData.value.length
        for(let i=0;i<tableData.value.length;i++) {
          const reg=new RegExp("\"","g");
          tableData.value[i].trainParams = ((JSON.stringify(tableData.value[i].trainParams))+"")
              .replace(reg,"")
              .replace("{","")
              .replace("}","")
              .split(",");
        }
        const route=useRoute()
      })
    };
    getpage();
    // 查询操作
    const handleSearch = () => {
      query.pageIndex = 1;
      getpage();
    };
    // 分页导航
    const handlePageChange = (val) => {
      query.pageIndex = val;
      getpage();
    };
    const handlePreList=(modelId)=>{
      router.push({
        path:'predictionList',
        query:{
          modelId:modelId,
        }
      })
    }
    //todo模型训练
    const handleTrain =(modelId) => {
      ElMessageBox( {
        title: "确定要训练吗？",
        showCancelButton: true,
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        beforeClose: (action, instance, done) => {
          if (action === 'confirm') {
            instance.confirmButtonLoading = true
            instance.confirmButtonText = '训练中...'
            let idx=modelId;
            console.log("modelId: "+idx);
            const payload={
              modelId: idx,
              userId: localStorage.getItem("ms_userId")
            }
            console.log(payload)
            train(payload).then(res=>{
              instance.confirmButtonLoading = false
              console.log("train_res: ",res);
              if (res.msg === '成功')
              {
                ElMessage.success("模型已经开始训练！")
                getpage();
                done()
              }
              else
              {
                ElMessage.error("训练失败!:"+res.msg);
                done()
              }
            }
            ).catch(err=>{
              console.log(err)
            });
          } else {
            done()
          }
        },
      })
    };
    const modelRes=ref();
    const handleTrainRes = (index) => {
      const reg=new RegExp("\"","g");
     modelRes.value= ((JSON.stringify(tableData.value[index].trainResults)+"")
            .replace(reg,"")
            .replace("{","")
            .replace("}","")
            .replace("[","")
            .split(","))
      let str=""
      for(let i=0;i<modelRes.value.length;i++){
        str=str+modelRes.value[i]
        str=str+"\n"
      }
       ElMessageBox.confirm(str)
      }

      const handleDeploy = (id) => {
        deployVisible.value = true
        deployModel.value = id
      }

      const goDeploy = () =>{
        const payload = {
          userId: localStorage.getItem("ms_userId"),
          modelId: deployModel.value,
          deploymentName: deployName.value
        }
        if(payload.deploymentName === undefined){
          alert('请输入必要信息！')
          return
        }
        deployVisible.value = false
        addDeployment(payload).then(res=>{
          if (res.msg === '成功'){
            ElMessage.success('开始部署！')
          }
          else {
            ElMessage.error('无法部署！')
          }
        })
      }

    const usemodelId=ref();
    //todo模型使用
     const editUseModel = (id) => {
      useModelVisible.value=true;
      usemodelId.value=id
    };

    let useform = reactive({
      file: "",
    });
        //todo模型使用
     const useModel = (fileId) => {
       if (fileId === ""){
         alert("请填写信息！")
         return
       }
      useModelVisible.value=false;
       let payload={
         modelId:usemodelId.value,
         fileInfoId:fileId,
         userId: localStorage.getItem("ms_userId"),
       }
       console.log(payload.fileInfoId)
       ElMessageBox( {
         title: "确定要预测吗？",
         showCancelButton: true,
         confirmButtonText: '确定',
         cancelButtonText: '取消',
         beforeClose: (action, instance, done) => {
           if (action === 'confirm') {
             instance.confirmButtonLoading = true
             instance.confirmButtonText = '预测中...'
             use(payload).then(res=>{
               instance.confirmButtonLoading = false
               console.log("predic_res: ",res);
               if (res.msg === '成功')
               {
                 ElMessage.success("已经使用该模型开始预测")
                 getpage();
                 done()
               }
               else
               {
                 console.log(res);
                 ElMessage.error("预测失败!失败码:"+res.msg);
                 done()
               }
             }).catch(err=>{
               console.log(err)
             });
           } else {
             done()
           }
         },
       })
       // use(data).then(res=>{
       //   console.log(res.data);
       // })
       // const router=useRouter()
       // const fileId=useform.file
     };

    const handleShare = (index) => {
      // 二次确认分享
      ElMessageBox.confirm("确定要分享到广场吗？", "提示", {
        type: "warning",
      })
        .then(() => {
          const payload ={
            userId: localStorage.getItem("ms_userId"),
            modelId: tableData.value[index].id
          }
          shareModel(payload).then(res=>{
            if(res.msg === '成功'){
              ElMessage.success("分享成功!")
            } else {
              ElMessage.error("分享失败!错误码:"+res.status)
            }
          });

        })
        .catch(() => {});
    };


    // 删除操作(单个)
    const handleDelete = (index) => {
      // 二次确认删除
      ElMessageBox.confirm("确定要删除吗？", "提示", {
        type: "warning",
      })
          .then(() => {
            // ElMessage.success("删除成功");
            // tableData.value.splice(index, 1);
            console.log("删除");
            let idx=tableData.value[index].modelId;
            console.log(idx);
            deleteModel(idx
            ).then(res=>{
              //console.log("deleteres",res);
              if(res.status===200){
                location.reload();
              }
            });

          })
          .catch(() => {});
    };
    //TODO
    const handleSelectionChange = (val) => {
      multipleSelection.value = val
    };

    //TODO 批量删除
    const handleBatchDelete =()=>{
      // 二次确认
      if(multipleSelection.value.length<=0){
        ElMessageBox.alert("请先勾选要删除的模型", '提示', {
          confirmButtonText: '好的'
        })
      }
      else{
        ElMessageBox.confirm("确定要删除这些模型吗？", "提示", {
          type: "warning",
        })
            .then(() => {
              let idList=[];
              for(let i=0;i<multipleSelection.value.length;i++){
                let id=multipleSelection.value[i]['id'];
                idList.push(id);
              }
              idList.sort();
              console.log(idList);
              for (let i = idList[idList.length-1]; i >=0 ; i--) {
                tableData.value.splice(i,1);
              }
              ElMessage.success("删除成功");
            })
            .catch(() => {});
      }
    };

    const editVisible = ref(false);
    let form = reactive({
      name: "",
      file: "",
      // classification:"",
      // feature:"",
    });
    let idx = -1;
    const handleEdit = (index, row) => {
      idx = index;
      Object.keys(form).forEach((item) => {
        form[item] = row[item];
      });
      editVisible.value = true;
    };

    const handleAlgorithmName=(name)=>{
      if (name === "DECISION_TREE_CLASSIFICATION") {
        return "决策树分类";
      } else if (name === "GRADIENT_BOOSTED_TREE_CLASSIFICATION") {
        return "梯度提升树分类";
      } else if (name === "LOGISTIC_REGRESSION_CLASSIFICATION") {
        return "对数几率回归分类";
      } else if (name === "MULTILAYER_PERCEPTRON_CLASSIFICATION") {
        return "多层感知器分类";
      } else if (name === "NAIVE_BAYES_CLASSIFICATION") {
        return "朴素贝叶斯分类";
      } else if (name === "XGBOOST_CLASSIFICATION") {
        return "XGBOOST分类";
      } else if (name === "RANDOM_FOREST_CLASSIFICATION") {
        return "随机森林分类";
      } else if (name === "K_MEANS_CLUSTERING") {
        return "K均值聚类";
      } else if (name === "DECISION_TREE_REGRESSION") {
        return "决策树回归算法";
      } else if (name === "RANDOM_FOREST_REGRESSION") {
        return "随机森林回归";
      }
    };

    return {
      router,
      usemodelId,
      query,
      tableData,
      pageTotal,
      fileList,
      useModelVisible,
      formLabelWidth,
      editVisible,
      form,
      useform,
      pipelineVisible,
      pplForm,
      deployVisible,
      deployName,
      deployModel,
      handleDeploy,
      goDeploy,
      handlePipeline,
      pipeline,
      handlePreList,
      handleSearch,
      handlePageChange,
      handleTrain,
      editUseModel,
      useModel,
      handleShare,
      handleDelete,
      handleSelectionChange,
      handleBatchDelete,
      handleEdit,
      getpage,
      handleTrainRes,
      handleAlgorithmName
    };
  },
};
</script>

<style scoped>
.handle-box {
  margin-bottom: 20px;
}

.handle-select {
  width: 120px;
}

.handle-input {
  width: 300px;
  display: inline-block;
}
.table {
  width: 100%;
  font-size: 14px;
}
.red {
  color: #ff0000;
}
.green {
  color: rgb(32, 220, 88)
}
.yellow{
  color:yellowgreen;
}
.orange{
  color: orange;
}
.mr10 {
  margin-right: 10px;
}
.table-td-thumb {
  display: block;
  margin: auto;
  width: 40px;
  height: 40px;
}
</style>
